package com.wan37.logic.server;

import com.wan37.logic.component.LogicWorkerHandlerCenter;
import com.wan37.logic.global.HandlerManager;
import com.wan37.logic.handler.LogicServerHandler;
import com.wan37.protobuf.ParseRegistryMap;
import com.wan37.protobuf.codec.ProtoPacketDecoder;
import com.wan37.protobuf.codec.ProtoPacketEncoder;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.net.InetSocketAddress;

/**
 * LogicServer逻辑服务器.
 * 负责处理游戏逻辑
 *
 * @author : luoyong
 * @date : 2020-05-28 09:48
 **/
@Component
public class LogicServer implements Runnable {

    private static final Logger logger = LoggerFactory.getLogger(LogicServer.class);

    /**
     * logicServer监听的端口
     */
    private int port;

    /**
     * 逻辑处理中心
     */
    @Autowired
    private LogicWorkerHandlerCenter logicWorkerHandlerCenter;

    @Override
    public void run() {
        startLogicServer(port);
    }

    private void startLogicServer(int port) {

        /**
         * logicServer作为服务器, 等待GateServer连接.
         */
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        ServerBootstrap serverBootstrap = new ServerBootstrap();
        serverBootstrap.group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer<SocketChannel>() {

                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {

                        ChannelPipeline pipeline = ch.pipeline();

                        //LengthFieldBasedFrameDecoder
                        pipeline.addLast("LengthFieldBasedFrameDecoder",
                                new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE,
                                        0,
                                        4,
                                        4,
                                        0));

                        pipeline.addLast("ProtobufPacketDecoder", new ProtoPacketDecoder());    //解码器
                        pipeline.addLast("LogicServerHandler", new LogicServerHandler(logicWorkerHandlerCenter));
                        pipeline.addLast("ProtobufPacketEncoder", new ProtoPacketEncoder());    //编码器
                    }
                });
        //绑定端口, 启动连接
        ChannelFuture future = serverBootstrap.bind(port);
        future.addListener(new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture future) throws Exception {
                if (future.isSuccess()) {
                    //初始化
                    ParseRegistryMap.initRegistry();    //初始化协议的解析器
                    HandlerManager.initMsgHandlers();   //初始化消息的处理器

                    logger.info("[LogicServer] 启动成功，等待连接...");
                } else {
                    logger.info("[LogicServer] 启动失败！！！");
                }
            }
        });
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public LogicWorkerHandlerCenter getLogicWorkerHandlerCenter() {
        return logicWorkerHandlerCenter;
    }

    public void setLogicWorkerHandlerCenter(LogicWorkerHandlerCenter logicWorkerHandlerCenter) {
        this.logicWorkerHandlerCenter = logicWorkerHandlerCenter;
    }
}
